<?php

function array_to_object($array = array())
{
    $data = new stdClass();
    if (!empty($array))
    {
        foreach ($array as $akey => $aval)
        {
            if (is_array($aval))
            {
                $aval = array_to_object($aval);
            }
            $data->{$akey} = $aval;
        }
    }
    return $data;
}

class xmlToObjArray
{

    var $xml_array = Array(); # xml array from parsed data

    function parse_xml_data($my_data, $options = false)
    {
        $this->xml_array = Array(0 => Array()); # clear previously parsed file and related variables; populate first element
        $my_parser = xml_parser_create();
        xml_set_object($my_parser, $this);
        xml_set_element_handler($my_parser, "xml_tag_open", "xml_tag_close");
        xml_set_character_data_handler($my_parser, "xml_tag_data");
        if (!xml_parse($my_parser, $my_data))
        {
            trigger_error("data can not be parsed", E_USER_ERROR); # inspect problems #die(sprintf("<br />\n<b>Error</b>:  %s on line <b>%d</b><br />\n", xml_error_string(xml_get_error_code($my_parser)), xml_get_current_line_number($my_parser)));
        }
        xml_parser_free($my_parser);
        if($options == true)
        {
            $xml  = array_to_object($this->xml_array);
        }
        else
        {
            $xml  = $this->xml_array;
        }
        return $xml;
    }

    var $my_branch = Array();

    function xml_tag_open($my_parser, $my_name, $my_attributes)
    {
        array_push($this->my_branch, $my_name); # add tag name to branch
        $this->xml_array[] = Array(); # nest array in xml array for data
        if (count($my_attributes))
        {
            $this->xml_array[count($this->xml_array) - 1]["ATTRIBUTES"] = $my_attributes; # nest attributes array
        }
    }

    function xml_tag_data($my_parser, $my_data)
    {
        if (isset($my_data) && $my_data != null)
            $this->xml_array[count($this->my_branch)][] = $my_data;

//        $this->xml_array[count($this->my_branch)]["TEXT_NODE"][] = $my_data; # add data to nested array
//        $this->xml_array[count($this->my_branch)]["NODES"][] = "TEXT_NODE"; # add text node to nested NODES array 
    }

    function xml_tag_close($my_parser, $my_name)
    {
        $this->xml_array[count($this->my_branch) - 1][$this->my_branch[count($this->my_branch) - 1]][] = $this->xml_array[count($this->xml_array) - 1]; # nest arrays to follow document structure
        array_pop($this->xml_array); # pop off element that was nested
        $this->xml_array[count($this->my_branch) - 1]["NODES"][] = $my_name; # add tag node to nested NODES array
        array_pop($this->my_branch); # update branch
    }

    function XMLToArray ( $xml , $recursive = false )
    {
        if ( ! $recursive )
        {
            $array = simplexml_load_string ( $xml ) ;
        }
        else
        {
            $array = $xml ;
        }

        $newArray = array () ;
        $array = ( array ) $array ;
        foreach ( $array as $key => $value )
        {
            $value = ( array ) $value ;
            if ( isset ( $value [ 0 ] ) )
            {
                $newArray [ $key ] = trim ( $value [ 0 ] ) ;
            }
            else
            {
                $newArray [ $key ] = $this->XMLToArray ( $value , true ) ;
            }
        }
        return $newArray ;
    }

}
?>